package com.sunni.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sunni.entity.Employee;
import com.sunni.entity.PageListRes;
import com.sunni.entity.QueryVo;
import com.sunni.service.EmployeeService;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.IOUtils;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import static org.apache.poi.ss.usermodel.CellType.*;

@Controller
@RequestMapping("/employee")
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;


    @RequestMapping("/getJspPage")
    @RequiresPermissions("employee:index")
    public String getJspPage(){
        return "employee";
    }

    @RequestMapping("/selectAll")
    @ResponseBody
    public PageListRes selectAll(QueryVo qv){
        return employeeService.selectAll(qv);
    }

    @RequestMapping("/addEmployee")
    @ResponseBody
    @RequiresPermissions("employee:add")
    public AjaxRes addEmployee(Employee employee){
        employee.getRoleList().forEach(role -> System.out.println("role = " + role));
        employee.setPassword(new Md5Hash(employee.getPassword(),employee.getUsername(),2).toString());
        return employeeService.addEmployee(employee);
    }

    @RequestMapping("/updateEmployee")
    @ResponseBody
    @RequiresPermissions("employee:edit")
    public AjaxRes editEmployee(Employee employee){
        System.out.println("------进入了修改");
        System.out.println("employee = " + employee);

        AjaxRes ajaxRes = new AjaxRes(false,"更新失败");
        try {
            employeeService.updateEmployee(employee);
            ajaxRes.setSuccess(true);
            ajaxRes.setMsg("更新成功");
        }catch (Exception e){

        }
        return ajaxRes;
    }


    /**
     * 点击删除按钮，设置
     * @param id 根据id更新
     * @return 状态
     */
    @RequestMapping("/updateState0")
    @ResponseBody
    @RequiresPermissions("employee:delete")
    public AjaxRes updateState0(Long id){
        System.out.println("要删除的id:::::"+id);
        AjaxRes ajaxRes = new AjaxRes(false,"设置离职失败");

        try {
            employeeService.updateState0(id);
            ajaxRes.setSuccess(true);
            ajaxRes.setMsg("设置离职成功");
        }catch (Exception e){
            System.out.println(e);
        }
        return ajaxRes;
    }


    /*员工页面，编辑，角色下拉框 数据回显*/
    @RequestMapping("/selectRolesByEid")
    @ResponseBody
    public List<Long> selectRolesByEid(Long eid){
//        System.out.println("selectRolesByEid--------------eid = " + eid);
        return employeeService.selectRolesByEid(eid);
    }



    /*处理 没有对应的操作的授权 报的500错误  告诉页面没有权限*/
    @ExceptionHandler(AuthorizationException.class ) /*出现AuthorizationException异常，就执行这个方法*/
    public void handleShiroException(HandlerMethod method , HttpServletResponse response) throws Exception{

        /*获取报错那个方法的注解，看看有没有ResponseBody这个注解*/
        ResponseBody responseBody = method.getMethodAnnotation(ResponseBody.class);

        if (responseBody != null){ /*有ResponseBody注解，说明前台发的是Ajax请求*/
                AjaxRes ajaxRes = new AjaxRes(false,"没有权限");
                String result = new ObjectMapper().writeValueAsString(ajaxRes);
                response.setCharacterEncoding("utf-8");
                response.getWriter().write(result);
        }else {/*没有ResponseBody注解，说明前台发的不是Ajax请求*/
                response.sendRedirect("/employee/getNoPermissionJsp");
        }
    }
    @RequestMapping("/getNoPermissionJsp")
    public String getNoPermissionJsp(){
        return "nopermission";
    }

    /*课时114-导出数据到excel*/
    @RequestMapping("/downloadExcel")
    @ResponseBody
    public void downloadExcel(HttpServletResponse response){
        try {
            System.out.println("-----downloadExcel-----");


            /*课时115-创建excel工作簿 sheet,,设置表头(列名)、写入员工信息*/
            //1.从数据库当中获取datagrid上的数据
            PageListRes pageListRes = employeeService.selectAll(new QueryVo(1, 10, null));
            List<Employee> employeeList = (List<Employee>) pageListRes.getRows();

            //2.创建excel, 写到excel里面
            HSSFWorkbook workbook = new HSSFWorkbook();
            /*sheet名*/
            HSSFSheet sheet = workbook.createSheet("员工数据");// 一个页(excel的sheet)

            /*设置表头(字段名)（角标从0开始，对应excel第一行）*/
            HSSFRow row = sheet.createRow(0);//创建了1行，角标从0开始
            //设置行的每列数据
            row.createCell(0).setCellValue("编号");
            row.createCell(1).setCellValue("姓名");
            row.createCell(2).setCellValue("入职日期");
            row.createCell(3).setCellValue("电话");
            row.createCell(4).setCellValue("电子邮件");

            /*把员工数据从数据库里面取出来，存到excel里面*/
            HSSFRow employeeRow = null;
            // 取出每一个员工，设置每列的数据
            for (int i = 0; i < employeeList.size(); i++) {
                Employee employee = employeeList.get(i);
                employeeRow = sheet.createRow(i + 1);//第0行是表头，已经设置好了，所以要从0+1开始，对应第二行
                employeeRow.createCell(0).setCellValue(employee.getId());
                employeeRow.createCell(1).setCellValue(employee.getUsername());
                /*日期类特殊，需要先判断，取出的日期是不是null*/
                if (employee.getInputtime() != null){
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    String inputtime = simpleDateFormat.format(employee.getInputtime());
                    employeeRow.createCell(2).setCellValue(inputtime);
                }else {
                    employeeRow.createCell(2).setCellValue("");
                }
                employeeRow.createCell(3).setCellValue(employee.getTel());
                employeeRow.createCell(4).setCellValue(employee.getEmail());
            }

            /*课时116-下载excel*/
            //3.响应给浏览器
            //表名、数据编码
            String fileName = new String("员工数据.xls".getBytes("utf-8"), "iso8859-1");
            response.setHeader("content-Disposition","attachment;filename="+fileName);
            workbook.write(response.getOutputStream());
        } catch (Exception e) {
            System.out.println("e = " + e);
        }
    }

    /*课时118-下载excel模板*/
    @RequestMapping("/downloadExcelTpl")
    @ResponseBody
    public void downloadExcelTpl(HttpServletRequest request,HttpServletResponse response){
        System.out.println("----downloadExcelTpl-----");
        FileInputStream is = null;
        try {
            String fileName = new String("EmployeeTpl.xls".getBytes("utf-8"), "iso8859-1");
            response.setHeader("content-Disposition","attachment;filename="+fileName);
            /*获取Excel模板的路径*/
            String realPath = request.getSession().getServletContext().getRealPath("static/ExcelTml.xls");
            /*读取文件（使用路径）*/
            is = new FileInputStream(realPath);
            /*输出流*/
            IOUtils.copy(is,response.getOutputStream());
        }catch (Exception e){
            System.out.println("e = " + e);
        }finally {
            if (is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    System.out.println("e = " + e);
                }
            }
        }
    }

    /*课时119-导入excel，读到行数（先去mvc文件，配置文件上传解析器）*/
    @RequestMapping("/uploadExcelFile")
    @ResponseBody
    public AjaxRes uploadExcelFile(MultipartFile excel){
        AjaxRes ajaxRes = new AjaxRes(false,"导入失败");
        try {

            HSSFWorkbook workbook = new HSSFWorkbook(excel.getInputStream());

            HSSFSheet sheet = workbook.getSheetAt(0);

            int lastRowNum = sheet.getLastRowNum();

            System.out.println("lastRowNum = " + lastRowNum);

            /*课时120：读取excel数据，写入数据库*/
            Row employeeRow = null;
            for (int i = 1; i <= lastRowNum; i++) {
                employeeRow = sheet.getRow(i);
                Employee employee = new Employee();
                getCellValue(employeeRow.getCell(0));
                employee.setUsername((String) getCellValue(employeeRow.getCell(1)));
                employee.setInputtime((Date) getCellValue(employeeRow.getCell(2)));
                employee.setTel(getCellValue(employeeRow.getCell(3)).toString());
                employee.setEmail((String) getCellValue(employeeRow.getCell(4)));
                employeeService.addEmployee(employee);
            }

            ajaxRes.setSuccess(true);
            ajaxRes.setMsg("导入成功");
        }catch (Exception e){
            System.out.println("e = " + e);
        }

        return ajaxRes;
    }

    private Object getCellValue(Cell cell){
        switch (cell.getCellType()) {
            case STRING:
                return cell.getRichStringCellValue().getString();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return cell.getDateCellValue();
                } else {
                    return cell.getNumericCellValue();
                }
            case BOOLEAN:
                return cell.getBooleanCellValue();
            case FORMULA:
                return cell.getCellFormula();
        }
        return cell;
    }




}
